home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectShow / Misc / DMOEnum / dmoenumdlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  23.2 KB  |  842 lines

  1. //------------------------------------------------------------------------------
  2. // File: DMOEnumDlg.cpp
  3. //
  4. // Desc: DirectShow sample code - implementation of dialog for device
  5. //       enumeration.
  6. //
  7. // Copyright (c) 2000-2001 Microsoft Corporation.  All rights reserved.
  8. //------------------------------------------------------------------------------
  9.  
  10.  
  11. #include "stdafx.h"
  12. #include "DMOEnum.h"
  13. #include "DMOEnumDlg.h"
  14.  
  15. #include "mfcdmoutil.h"
  16. #include "namedguid.h"
  17.  
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CAboutDlg dialog used for App About
  26.  
  27. class CAboutDlg : public CDialog
  28. {
  29. public:
  30.     CAboutDlg();
  31.  
  32. // Dialog Data
  33.     //{{AFX_DATA(CAboutDlg)
  34.     enum { IDD = IDD_ABOUTBOX };
  35.     //}}AFX_DATA
  36.  
  37.     // ClassWizard generated virtual function overrides
  38.     //{{AFX_VIRTUAL(CAboutDlg)
  39.     protected:
  40.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  41.     //}}AFX_VIRTUAL
  42.  
  43. // Implementation
  44. protected:
  45.     //{{AFX_MSG(CAboutDlg)
  46.     //}}AFX_MSG
  47.     DECLARE_MESSAGE_MAP()
  48. };
  49.  
  50. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  51. {
  52.     //{{AFX_DATA_INIT(CAboutDlg)
  53.     //}}AFX_DATA_INIT
  54. }
  55.  
  56. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  57. {
  58.     CDialog::DoDataExchange(pDX);
  59.     //{{AFX_DATA_MAP(CAboutDlg)
  60.     //}}AFX_DATA_MAP
  61. }
  62.  
  63. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  64.     //{{AFX_MSG_MAP(CAboutDlg)
  65.         // No message handlers
  66.     //}}AFX_MSG_MAP
  67. END_MESSAGE_MAP()
  68.  
  69. /////////////////////////////////////////////////////////////////////////////
  70. // CDMOEnumDlg dialog
  71.  
  72. CDMOEnumDlg::CDMOEnumDlg(CWnd* pParent /*=NULL*/)
  73.     : CDialog(CDMOEnumDlg::IDD, pParent)
  74. {
  75.     //{{AFX_DATA_INIT(CDMOEnumDlg)
  76.     //}}AFX_DATA_INIT
  77.     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  78.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  79. }
  80.  
  81. void CDMOEnumDlg::DoDataExchange(CDataExchange* pDX)
  82. {
  83.     CDialog::DoDataExchange(pDX);
  84.     //{{AFX_DATA_MAP(CDMOEnumDlg)
  85.     DDX_Control(pDX, IDC_STATIC_OUT_TYPE, m_StrOutType);
  86.     DDX_Control(pDX, IDC_STATIC_OUT_SUBYTPE, m_StrOutSubtype);
  87.     DDX_Control(pDX, IDC_STATIC_IN_TYPE, m_StrInType);
  88.     DDX_Control(pDX, IDC_STATIC_IN_SUBTYPE, m_StrInSubtype);
  89.     DDX_Control(pDX, IDC_CHECK_OUT_SUPPORTS_QC, m_CheckOutQC);
  90.     DDX_Control(pDX, IDC_CHECK_IN_SUPPORTS_QC, m_CheckInQC);
  91.     DDX_Control(pDX, IDC_STATIC_IN_FORMAT, m_StrInFormat);
  92.     DDX_Control(pDX, IDC_STATIC_OUT_FORMAT, m_StrOutFormat);
  93.     DDX_Control(pDX, IDC_CHECK_OUT_FIXED, m_CheckOutFixedSize);
  94.     DDX_Control(pDX, IDC_CHECK_OUT_WHOLE_SAMPLES, m_CheckOutWholeSamples);
  95.     DDX_Control(pDX, IDC_CHECK_OUT_OPTIONAL, m_CheckOutOptional);
  96.     DDX_Control(pDX, IDC_CHECK_OUT_ONESAMPLE, m_CheckOutOneSample);
  97.     DDX_Control(pDX, IDC_CHECK_OUT_DISCARDABLE, m_CheckOutDiscardable);
  98.     DDX_Control(pDX, IDC_CHECK_IN_WHOLE_SAMPLES, m_CheckInWholeSamples);
  99.     DDX_Control(pDX, IDC_CHECK_IN_ONESAMPLE, m_CheckInOneSample);
  100.     DDX_Control(pDX, IDC_CHECK_IN_HOLDSBUFFERS, m_CheckInHoldsBuffers);
  101.     DDX_Control(pDX, IDC_CHECK_IN_FIXED, m_CheckInFixedSize);
  102.     DDX_Control(pDX, IDC_STATIC_OUTPUT_STREAMS, m_nOutputStreams);
  103.     DDX_Control(pDX, IDC_STATIC_INPUT_STREAMS, m_nInputStreams);
  104.     DDX_Control(pDX, IDC_LIST_OUTPUT_STREAMS, m_ListOutputStreams);
  105.     DDX_Control(pDX, IDC_LIST_INPUT_STREAMS, m_ListInputStreams);
  106.     DDX_Control(pDX, IDC_STATIC_NUM_OTYPES, m_nOutputTypes);
  107.     DDX_Control(pDX, IDC_STATIC_NUM_ITYPES, m_nInputTypes);
  108.     DDX_Control(pDX, IDC_LIST_OUTPUT_TYPES, m_ListOutputTypes);
  109.     DDX_Control(pDX, IDC_LIST_INPUT_TYPES, m_ListInputTypes);
  110.     DDX_Control(pDX, IDC_CHECK_KEYED, m_bCheckKeyed);
  111.     DDX_Control(pDX, IDC_STATIC_FILENAME, m_StrFilename);
  112.     DDX_Control(pDX, IDC_STATIC_FILTERS, m_StrFilters);
  113.     DDX_Control(pDX, IDC_STATIC_CLASSES, m_StrClasses);
  114.     DDX_Control(pDX, IDC_LIST_FILTERS, m_FilterList);
  115.     DDX_Control(pDX, IDC_LIST_DEVICES, m_DeviceList);
  116.     //}}AFX_DATA_MAP
  117. }
  118.  
  119. BEGIN_MESSAGE_MAP(CDMOEnumDlg, CDialog)
  120.     //{{AFX_MSG_MAP(CDMOEnumDlg)
  121.     ON_WM_SYSCOMMAND()
  122.     ON_WM_PAINT()
  123.     ON_WM_QUERYDRAGICON()
  124.     ON_LBN_SELCHANGE(IDC_LIST_DEVICES, OnSelchangeListDevices)
  125.     ON_WM_CLOSE()
  126.     ON_LBN_SELCHANGE(IDC_LIST_FILTERS, OnSelchangeListFilters)
  127.     ON_BN_CLICKED(IDC_CHECK_KEYED, OnCheckKeyed)
  128.     ON_LBN_SELCHANGE(IDC_LIST_INPUT_STREAMS, OnSelchangeListInputStreams)
  129.     ON_LBN_SELCHANGE(IDC_LIST_OUTPUT_STREAMS, OnSelchangeListOutputStreams)
  130.     //}}AFX_MSG_MAP
  131. END_MESSAGE_MAP()
  132.  
  133.  
  134. /////////////////////////////////////////////////////////////////////////////
  135. // CDMOEnumDlg message handlers
  136.  
  137. void CDMOEnumDlg::OnSysCommand(UINT nID, LPARAM lParam)
  138. {
  139.     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  140.     {
  141.         CAboutDlg dlgAbout;
  142.         dlgAbout.DoModal();
  143.     }
  144.     else
  145.     {
  146.         CDialog::OnSysCommand(nID, lParam);
  147.     }
  148. }
  149.  
  150.  
  151. // If you add a minimize button to your dialog, you will need the code below
  152. //  to draw the icon.  For MFC applications using the document/view model,
  153. //  this is automatically done for you by the framework.
  154.  
  155. void CDMOEnumDlg::OnPaint() 
  156. {
  157.     if (IsIconic())
  158.     {
  159.         CPaintDC dc(this); // device context for painting
  160.  
  161.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  162.  
  163.         // Center icon in client rectangle
  164.         int cxIcon = GetSystemMetrics(SM_CXICON);
  165.         int cyIcon = GetSystemMetrics(SM_CYICON);
  166.         CRect rect;
  167.         GetClientRect(&rect);
  168.         int x = (rect.Width() - cxIcon + 1) / 2;
  169.         int y = (rect.Height() - cyIcon + 1) / 2;
  170.  
  171.         // Draw the icon
  172.         dc.DrawIcon(x, y, m_hIcon);
  173.     }
  174.     else
  175.     {
  176.         CDialog::OnPaint();
  177.     }
  178. }
  179.  
  180. // The system calls this to obtain the cursor to display while the user drags
  181. //  the minimized window.
  182. HCURSOR CDMOEnumDlg::OnQueryDragIcon()
  183. {
  184.     return (HCURSOR) m_hIcon;
  185. }
  186.  
  187.  
  188. BOOL CDMOEnumDlg::OnInitDialog()
  189. {
  190.     CDialog::OnInitDialog();
  191.  
  192.     // Add "About..." menu item to system menu.
  193.  
  194.     // IDM_ABOUTBOX must be in the system command range.
  195.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  196.     ASSERT(IDM_ABOUTBOX < 0xF000);
  197.  
  198.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  199.     if (pSysMenu != NULL)
  200.     {
  201.         CString strAboutMenu;
  202.         strAboutMenu.LoadString(IDS_ABOUTBOX);
  203.         if (!strAboutMenu.IsEmpty())
  204.         {
  205.             pSysMenu->AppendMenu(MF_SEPARATOR);
  206.             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  207.         }
  208.     }
  209.  
  210.     // Set the icon for this dialog.  The framework does this automatically
  211.     //  when the application's main window is not a dialog
  212.     SetIcon(m_hIcon, TRUE);            // Set big icon
  213.     SetIcon(m_hIcon, FALSE);        // Set small icon
  214.     
  215.     ////////////////////////////////////////////////////////////////////////
  216.     //
  217.     //  DirectShow-specific initialization code
  218.  
  219.     CoInitialize(NULL);
  220.     m_pDMO=0;
  221.     m_pGB=0;
  222.  
  223.     // Include keyed DMOs in our search by default
  224.     m_bCheckKeyed.SetCheck(TRUE);
  225.  
  226.     // Enumerate and display the DMO category list
  227.     FillCategoryList();
  228.  
  229.     return TRUE;  // return TRUE  unless you set the focus to a control
  230. }
  231.  
  232.  
  233. void CDMOEnumDlg::FillCategoryList(void)
  234. {
  235.     // Clear listboxes
  236.     ClearDeviceList();
  237.     ClearFilterList();
  238.  
  239.     // Fill the category list box with the categories to display,
  240.     // using the names stored in the DMO_CATEGORY_INFO array.
  241.     // See DMOEnumDlg.H for a category description.
  242.     for (int i=0; i < NUM_CATEGORIES; i++)
  243.         m_DeviceList.AddString(dmo_categories[i].szName);
  244.  
  245.     // Update listbox title with number of classes
  246.     SetNumClasses(NUM_CATEGORIES);
  247.  
  248.     // Select the first category to show useful information
  249.     m_DeviceList.SetCurSel(0);
  250.     OnSelchangeListDevices();
  251. }
  252.  
  253. void CDMOEnumDlg::SetNumClasses(int nClasses)
  254. {
  255.     TCHAR szClasses[64];
  256.  
  257.     wsprintf(szClasses, TEXT("%s (%d found)\0"), STR_CLASSES, nClasses);
  258.     m_StrClasses.SetWindowText(szClasses);
  259. }
  260.  
  261. void CDMOEnumDlg::SetNumFilters(int nFilters)
  262. {
  263.     TCHAR szFilters[64];
  264.  
  265.     if (nFilters)
  266.         wsprintf(szFilters, TEXT("%s (%d found)\0"), STR_FILTERS, nFilters);
  267.     else
  268.         wsprintf(szFilters, TEXT("%s\0"), STR_FILTERS);
  269.  
  270.     m_StrFilters.SetWindowText(szFilters);
  271. }
  272.  
  273. void CDMOEnumDlg::OnCheckKeyed() 
  274. {
  275.     // Reenumerate the related filters, since the list may
  276.     // have changed to add or removed keyed filters.
  277.     OnSelchangeListDevices();
  278. }
  279.  
  280. void CDMOEnumDlg::ClearDeviceList(void)
  281. {
  282.     // Clean up
  283.     m_DeviceList.ResetContent();
  284.     SetNumClasses(0);
  285. }
  286.  
  287. void CDMOEnumDlg::ClearFilterList(void)
  288. {
  289.     CLSID *pStoredId = NULL;
  290.     
  291.     int nCount = m_FilterList.GetCount();
  292.  
  293.     // Delete any CLSID pointers that were stored in the listbox item data
  294.     for (int i=0; i < nCount; i++)
  295.     {
  296.         pStoredId = (CLSID *) m_FilterList.GetItemDataPtr(i);
  297.         if (pStoredId != 0)
  298.         {
  299.             delete pStoredId;
  300.             pStoredId = NULL;
  301.         }
  302.     }
  303.  
  304.     // Clean up
  305.     m_FilterList.ResetContent();
  306.     SetNumFilters(0);
  307.     m_StrFilename.SetWindowText(TEXT("<No DMO selected>"));
  308. }
  309.  
  310. void CDMOEnumDlg::ClearTypeLists(void)
  311. {
  312.     // Clear the type boxes
  313.     m_ListInputTypes.ResetContent();
  314.     m_ListOutputTypes.ResetContent();
  315.  
  316.     m_nInputTypes.SetWindowText(TEXT("0\0"));
  317.     m_nOutputTypes.SetWindowText(TEXT("0\0"));
  318. }
  319.  
  320. void CDMOEnumDlg::OnClose() 
  321. {
  322.     // Free any stored CLSID pointers (in listbox item data ptr area)
  323.     ReleaseDMO();
  324.     ClearFilterList();
  325.     ClearDeviceList();
  326.  
  327.     CoUninitialize();
  328.     CDialog::OnClose();
  329. }
  330.  
  331. void CDMOEnumDlg::ReleaseDMO(void)
  332. {
  333.     SAFE_RELEASE(m_pDMO);
  334.     SAFE_RELEASE(m_pGB);
  335.  
  336.     // Clear any information set on the dialog for the last DMO
  337.     ClearDMOInfo();
  338. }
  339.  
  340. void CDMOEnumDlg::ClearDMOInfo()
  341. {
  342.     // Clear DMO-specific information
  343.     m_ListInputStreams.ResetContent();
  344.     m_ListOutputStreams.ResetContent();
  345.     m_nInputStreams.SetWindowText(TEXT("In Streams: 0\0"));
  346.     m_nOutputStreams.SetWindowText(TEXT("Out Streams: 0\0"));
  347.  
  348.     // Input settings
  349.     m_CheckInWholeSamples.SetCheck(FALSE);
  350.     m_CheckInOneSample.SetCheck(FALSE);
  351.     m_CheckInFixedSize.SetCheck(FALSE);
  352.     m_CheckInHoldsBuffers.SetCheck(FALSE);
  353.     m_StrInFormat.SetWindowText(STR_UNKNOWN);
  354.     m_StrInType.SetWindowText(STR_UNKNOWN);
  355.     m_StrInSubtype.SetWindowText(STR_UNKNOWN);
  356.     m_CheckInQC.SetCheck(FALSE);
  357.  
  358.     // Output settings
  359.     m_CheckOutWholeSamples.SetCheck(FALSE);
  360.     m_CheckOutOneSample.SetCheck(FALSE);
  361.     m_CheckOutFixedSize.SetCheck(FALSE);
  362.     m_CheckOutDiscardable.SetCheck(FALSE);
  363.     m_CheckOutOptional.SetCheck(FALSE);
  364.     m_StrOutFormat.SetWindowText(STR_UNKNOWN);
  365.     m_StrOutType.SetWindowText(STR_UNKNOWN);
  366.     m_StrOutSubtype.SetWindowText(STR_UNKNOWN);
  367.     m_CheckOutQC.SetCheck(FALSE);
  368. }
  369.  
  370.  
  371. void CDMOEnumDlg::OnSelchangeListFilters() 
  372. {
  373.     const CLSID *clsid;
  374.  
  375.     // Get the currently selected category name
  376.     int nItem = m_FilterList.GetCurSel();
  377.     
  378.     // Read the CLSID pointer from the list box's item data
  379.     clsid = (CLSID *) m_FilterList.GetItemDataPtr(nItem);
  380.  
  381.     // Find the filter filename in the registry (by CLSID)
  382.     if (clsid != 0)
  383.     {
  384.         // Display the DMO's server filename
  385.         ShowFilenameByCLSID(*clsid);
  386.  
  387.         // Show media types/subtypes used by this DMO
  388.         AddTypeInfo(clsid);
  389.  
  390.         // Display DMO-specific information        
  391.         ReleaseDMO();
  392.         ShowSelectedDMOInfo(clsid);
  393.     }
  394. }
  395.  
  396.  
  397. void CDMOEnumDlg::OnSelchangeListDevices() 
  398. {
  399.     HRESULT hr;    
  400.     IEnumDMO *pEnum = NULL;
  401.     DWORD dwFlags = m_bCheckKeyed.GetCheck() ? DMO_ENUMF_INCLUDE_KEYED : 0;
  402.  
  403.     // Get the currently selected category name
  404.     int nItem = m_DeviceList.GetCurSel();
  405.     const GUID *clsid;
  406.     
  407.     // Read the CLSID pointer from our hard-coded array of
  408.     // documented filter categories
  409.     clsid = dmo_categories[nItem].pclsid;
  410.  
  411.     ClearTypeLists();
  412.     ReleaseDMO();
  413.  
  414.     // Enumerate all DMOs of the selected category  
  415.     hr = DMOEnum(*clsid, dwFlags, 0, NULL, 0, NULL, &pEnum);
  416.     if (FAILED(hr))
  417.         return;
  418.  
  419.     // Enumerate all filters using the new category enumerator
  420.     hr = EnumDMOs(pEnum);
  421.  
  422.     // Now that the DMOs (if any) are enumerated and added 
  423.     // to the list, go ahead and select the first one.
  424.     m_FilterList.SetCurSel(0);
  425.     OnSelchangeListFilters();
  426.  
  427.     SAFE_RELEASE(pEnum);
  428. }
  429.  
  430.  
  431. void CDMOEnumDlg::AddFilter(
  432.     const TCHAR *szFilterName,
  433.     const GUID *pCatGuid)
  434. {
  435.     // Allocate a new CLSID, whose pointer will be stored in 
  436.     // the listbox.  When the listbox is cleared, these will be deleted.
  437.     CLSID *pclsid = new CLSID;
  438.  
  439.     // Add the category name and a pointer to its CLSID to the list box
  440.     int nSuccess  = m_FilterList.AddString(szFilterName);
  441.     int nIndexNew = m_FilterList.FindStringExact(-1, szFilterName);
  442.  
  443.     if (pclsid)
  444.     {
  445.         *pclsid = *pCatGuid;
  446.         nSuccess = m_FilterList.SetItemDataPtr(nIndexNew, pclsid);
  447.     }
  448. }
  449.  
  450.  
  451. HRESULT CDMOEnumDlg::EnumDMOs(IEnumDMO *pEnumCat)
  452. {
  453.     HRESULT hr=S_OK;
  454.     ULONG cFetched;
  455.     int nFilters=0;
  456.     WCHAR *wszName;
  457.     CLSID clsid;
  458.  
  459.     // Clear the current filter list
  460.     ClearFilterList();
  461.  
  462.     // If there are no filters of a requested type, show default string
  463.     if (!pEnumCat)
  464.     {
  465.         m_FilterList.AddString(TEXT("<< No entries >>"));
  466.         SetNumFilters(nFilters);
  467.         return S_FALSE;
  468.     }
  469.  
  470.     // Enumerate all items associated with the moniker
  471.     while(pEnumCat->Next(1, &clsid, &wszName, &cFetched) == S_OK)
  472.     {
  473.         nFilters++;
  474.         CString str(wszName);
  475.  
  476.         // Add this DMO's name and CLSID to the listbox
  477.         AddFilter(str, &clsid);
  478.         CoTaskMemFree(wszName);
  479.     }
  480.  
  481.     // If no DMOs matched the query, show a default item
  482.     if (nFilters == 0)
  483.         m_FilterList.AddString(TEXT("<< No entries >>"));
  484.  
  485.     // Update count of enumerated filters
  486.     SetNumFilters(nFilters);
  487.     return hr;
  488. }
  489.  
  490.  
  491. void CDMOEnumDlg::GetTypeSubtypeString(TCHAR *szCLSID, DMO_PARTIAL_MEDIATYPE& aList)
  492. {
  493.     HRESULT hr;
  494.     CString strType, strSubtype;
  495.     int j;
  496.  
  497.     LPOLESTR szType, szSubtype;
  498.  
  499.     // Convert binary CLSIDs to readable versions
  500.     hr = StringFromCLSID(aList.type, &szType);
  501.     if(FAILED(hr))
  502.         return;
  503.     hr = StringFromCLSID(aList.subtype, &szSubtype);
  504.     if(FAILED(hr))
  505.         return;
  506.  
  507.     // Set default type/subtype strings to their actual GUID values
  508.     strType = szType;
  509.     strSubtype = szSubtype;
  510.  
  511.     // Find type GUID's name in the named guids table
  512.     j=0;
  513.     while (rgng[j].pguid != 0)
  514.     {
  515.         if(aList.type == *(rgng[j].pguid))
  516.         {
  517.             strType = rgng[j].psz;  // Save type name
  518.             break;
  519.         }
  520.         j++;
  521.     }
  522.  
  523.     // Find subtype GUID's name in the named guids table
  524.     j=0;
  525.     while (rgng[j].pguid != 0)
  526.     {
  527.         if(aList.subtype == *(rgng[j].pguid))
  528.         {
  529.             strSubtype = rgng[j].psz; // Save subtype name
  530.             break;
  531.         }
  532.         j++;
  533.     }
  534.  
  535.     // Build a string with the type/subtype information.
  536.     // If a friendly name was found, it will be used.
  537.     // Otherwise, the type/subtype's raw GUID will be displayed.
  538.     wsprintf(szCLSID, TEXT("%s\t%s"), strType, strSubtype);
  539. }
  540.  
  541.  
  542. void CDMOEnumDlg::AddTypeInfo(const GUID *pCLSID)
  543. {
  544.     const int NUM_PAIRS=20;
  545.     HRESULT hr;
  546.     DMO_PARTIAL_MEDIATYPE aInputTypes[NUM_PAIRS]={0}, 
  547.                           aOutputTypes[NUM_PAIRS]={0};
  548.     ULONG ulNumInputsSupplied, ulNumOutputsSupplied;
  549.     ULONG ulNumInputTypes=NUM_PAIRS, ulNumOutputTypes=NUM_PAIRS, i;
  550.     TCHAR szCLSID[128];
  551.  
  552.     // Clear the type/subtype GUID boxes
  553.     ClearTypeLists();
  554.  
  555.     // Read type/subtype information
  556.     hr = DMOGetTypes(
  557.         *pCLSID,
  558.         ulNumInputTypes,
  559.         &ulNumInputsSupplied,
  560.         aInputTypes,
  561.         ulNumOutputTypes,
  562.         &ulNumOutputsSupplied,
  563.         aOutputTypes);
  564.  
  565.     if (FAILED(hr))
  566.         return;
  567.  
  568.     // Display the number of input/output type/subtype pairs found
  569.     TCHAR szNum[10];
  570.     wsprintf(szNum, TEXT("%d"), ulNumInputsSupplied);
  571.     m_nInputTypes.SetWindowText(szNum);
  572.     wsprintf(szNum, TEXT("%d"), ulNumOutputsSupplied);
  573.     m_nOutputTypes.SetWindowText(szNum);
  574.  
  575.     // Show input type/subtype pairs
  576.     for (i=0; i<ulNumInputsSupplied; i++)
  577.     {
  578.         GetTypeSubtypeString(szCLSID, aInputTypes[i]);
  579.         m_ListInputTypes.AddString(szCLSID);
  580.     }
  581.  
  582.     // Show output type/subtype pairs
  583.     for (i=0; i<ulNumOutputsSupplied; i++)
  584.     {
  585.         GetTypeSubtypeString(szCLSID, aOutputTypes[i]);
  586.         m_ListOutputTypes.AddString(szCLSID);
  587.     }
  588. }
  589.  
  590.  
  591. void CDMOEnumDlg::ShowFilenameByCLSID(REFCLSID clsid)
  592. {
  593.     HRESULT hr;
  594.     LPOLESTR strCLSID;
  595.  
  596.     // Convert binary CLSID to a readable version
  597.     hr = StringFromCLSID(clsid, &strCLSID);
  598.     if(SUCCEEDED(hr))
  599.     {
  600.         TCHAR szKey[512];
  601.         CString strQuery(strCLSID);
  602.  
  603.         // Create key name for reading filename registry
  604.         wsprintf(szKey, TEXT("Software\\Classes\\CLSID\\%s\\InprocServer32\0"),
  605.                  strQuery);
  606.  
  607.         // Free memory associated with strCLSID (allocated in StringFromCLSID)
  608.         CoTaskMemFree(strCLSID);
  609.  
  610.         HKEY hkeyFilter=0;
  611.         int rc=0;
  612.  
  613.         // Open the CLSID key that contains information about the filter
  614.         rc = RegOpenKey(HKEY_LOCAL_MACHINE, szKey, &hkeyFilter);
  615.         if (rc == ERROR_SUCCESS)
  616.         {
  617.             DWORD dwSize=MAX_PATH;
  618.             BYTE pbFilename[MAX_PATH];
  619.  
  620.             rc = RegQueryValueEx(hkeyFilter, NULL,  // Read (Default) value
  621.                                  NULL, NULL, pbFilename, &dwSize);
  622.  
  623.             if (rc == ERROR_SUCCESS)
  624.             {
  625.                 TCHAR szFilename[MAX_PATH];
  626.                 wsprintf(szFilename, TEXT("%s\0"), pbFilename);
  627.                 m_StrFilename.SetWindowText(szFilename);
  628.             }
  629.             else
  630.                 m_StrFilename.SetWindowText(TEXT("<Unknown>\0"));
  631.  
  632.             rc = RegCloseKey(hkeyFilter);
  633.         }
  634.     }
  635. }
  636.  
  637.  
  638. void CDMOEnumDlg::GetFormatString(TCHAR *szFormat, DMO_MEDIA_TYPE *pType)
  639. {
  640.     int i=0;
  641.  
  642.     // Find format GUID's name in the named guids table
  643.     while (rgng[i].pguid != 0)
  644.     {
  645.         if(pType->formattype == *(rgng[i].pguid))
  646.         {
  647.             wsprintf(szFormat, TEXT("%s\0"), rgng[i].psz);
  648.             return;
  649.         }
  650.         i++;
  651.     }
  652.  
  653.     // If we got here, there was no match
  654.     wsprintf(szFormat, TEXT("Format_None\0"));
  655. }
  656.  
  657. void CDMOEnumDlg::GetGUIDString(TCHAR *szString, GUID *pGUID)
  658. {
  659.     int i=0;
  660.  
  661.     // Find GUID's name in the named guids table
  662.     while (rgng[i].pguid != 0)
  663.     {
  664.         if(*pGUID == *(rgng[i].pguid))
  665.         {
  666.             wsprintf(szString, TEXT("%s\0"), rgng[i].psz);
  667.             return;
  668.         }
  669.         i++;
  670.     }
  671.  
  672.     // If we got here, there was no match
  673.     wsprintf(szString, TEXT("GUID_NULL\0"));
  674. }
  675.  
  676.  
  677. void CDMOEnumDlg::ShowSelectedDMOInfo(const GUID *pCLSID) 
  678. {
  679.     HRESULT hr;
  680.     TCHAR sz[64];
  681.  
  682.     // Create an instance of the selected DMO
  683.     hr = CoCreateInstance(*pCLSID, NULL, 
  684.                           CLSCTX_INPROC, IID_IMediaObject, 
  685.                           (void **)&m_pDMO);
  686.     if (FAILED(hr))
  687.     {
  688.         MessageBeep(0);
  689.         return;
  690.     }
  691.        
  692.     // Read and display information about its input/output streams
  693.     DWORD dwInStream=0, dwOutStream=0, dwCount;
  694.  
  695.     hr = m_pDMO->GetStreamCount(&dwInStream, &dwOutStream);
  696.     if (FAILED(hr))
  697.     {
  698.         MessageBeep(0);
  699.         return;
  700.     }
  701.  
  702.     // Display the number of streams used by this DMO
  703.     wsprintf(sz, TEXT("In Streams: %d"), dwInStream);
  704.     m_nInputStreams.SetWindowText(sz);
  705.     wsprintf(sz, TEXT("Out Streams: %d"), dwOutStream);
  706.     m_nOutputStreams.SetWindowText(sz);
  707.  
  708.     // Fill stream list boxes
  709.     for (dwCount=0; dwCount < dwInStream; dwCount++)
  710.     {
  711.         wsprintf(sz, TEXT("In %d"), dwCount);
  712.         m_ListInputStreams.AddString(sz);
  713.     }
  714.     for (dwCount=0; dwCount < dwOutStream; dwCount++)
  715.     {
  716.         wsprintf(sz, TEXT("Out %d"), dwCount);
  717.         m_ListOutputStreams.AddString(sz);
  718.     }
  719.  
  720.     // Select the first item in each list, if it exists
  721.     if (dwInStream > 0)
  722.     {
  723.         m_ListInputStreams.SetCurSel(0);
  724.         OnSelchangeListInputStreams();
  725.     }
  726.     if (dwOutStream > 0)
  727.     {
  728.         m_ListOutputStreams.SetCurSel(0);
  729.         OnSelchangeListOutputStreams();
  730.     }
  731. }
  732.  
  733.  
  734. void CDMOEnumDlg::OnSelchangeListInputStreams() 
  735. {
  736.     HRESULT hr;
  737.     TCHAR sz[64];
  738.     int nSel = m_ListInputStreams.GetCurSel();
  739.     DWORD dwFlags=0;
  740.  
  741.     //
  742.     // Display relevant information about input stream
  743.     //
  744.     if (!m_pDMO)
  745.         return;
  746.  
  747.     // Read input stream information flags
  748.     hr = m_pDMO->GetInputStreamInfo(nSel, &dwFlags);
  749.     if (FAILED(hr))
  750.     {
  751.         MessageBeep(0);
  752.         return;
  753.     }
  754.  
  755.     // Set stream info checkboxes
  756.     m_CheckInWholeSamples.SetCheck(dwFlags & DMO_INPUT_STREAMF_WHOLE_SAMPLES);
  757.     m_CheckInOneSample.SetCheck(dwFlags & DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER);
  758.     m_CheckInFixedSize.SetCheck(dwFlags & DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE);
  759.     m_CheckInHoldsBuffers.SetCheck(dwFlags & DMO_INPUT_STREAMF_HOLDS_BUFFERS);
  760.  
  761.     // Read preferred input type information.  The media type/subtypes
  762.     // are arranged in order of preference, starting from zero.
  763.     DMO_MEDIA_TYPE dmt={0};
  764.     hr = m_pDMO->GetInputType(nSel, 0, &dmt);
  765.  
  766.     if (SUCCEEDED(hr))
  767.     {
  768.         GetFormatString(sz, &dmt);
  769.         m_StrInFormat.SetWindowText(sz);
  770.         GetGUIDString(sz, &dmt.majortype);
  771.         m_StrInType.SetWindowText(sz);
  772.         GetGUIDString(sz, &dmt.subtype);
  773.         m_StrInSubtype.SetWindowText(sz);
  774.  
  775.         MoFreeMediaType(&dmt);
  776.     }
  777.  
  778.     // Does this DMO support quality control?
  779.     IDMOQualityControl *pQC=0;
  780.     hr = m_pDMO->QueryInterface(IID_IDMOQualityControl, (void **) &pQC);
  781.     if (SUCCEEDED(hr))
  782.     {
  783.         m_CheckInQC.SetCheck(TRUE);
  784.         pQC->Release();
  785.     }
  786. }
  787.  
  788. void CDMOEnumDlg::OnSelchangeListOutputStreams() 
  789. {
  790.     HRESULT hr;
  791.     TCHAR sz[64];
  792.     int nSel = m_ListInputStreams.GetCurSel();
  793.     DWORD dwFlags=0;
  794.  
  795.     //
  796.     // Display relevant information about output stream
  797.     //
  798.     if (!m_pDMO)
  799.         return;
  800.  
  801.     // Read output stream information flags
  802.     hr = m_pDMO->GetOutputStreamInfo(nSel, &dwFlags);
  803.     if (FAILED(hr))
  804.     {
  805.         MessageBeep(0);
  806.         return;
  807.     }
  808.  
  809.     // Set stream info checkboxes
  810.     m_CheckOutWholeSamples.SetCheck(dwFlags & DMO_OUTPUT_STREAMF_WHOLE_SAMPLES);
  811.     m_CheckOutOneSample.SetCheck(dwFlags & DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER);
  812.     m_CheckOutFixedSize.SetCheck(dwFlags & DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE);
  813.     m_CheckOutDiscardable.SetCheck(dwFlags & DMO_OUTPUT_STREAMF_DISCARDABLE);
  814.     m_CheckOutOptional.SetCheck(dwFlags & DMO_OUTPUT_STREAMF_OPTIONAL);
  815.  
  816.     // Read preferred output type information
  817.     DMO_MEDIA_TYPE dmt={0};
  818.     hr = m_pDMO->GetOutputType(nSel, 0, &dmt);
  819.  
  820.     if (SUCCEEDED(hr))
  821.     {
  822.         GetFormatString(sz, &dmt);
  823.         m_StrOutFormat.SetWindowText(sz);
  824.         GetGUIDString(sz, &dmt.majortype);
  825.         m_StrOutType.SetWindowText(sz);
  826.         GetGUIDString(sz, &dmt.subtype);
  827.         m_StrOutSubtype.SetWindowText(sz);
  828.  
  829.         MoFreeMediaType(&dmt);
  830.     }
  831.  
  832.     // Does this DMO support quality control?
  833.     IDMOQualityControl *pQC=0;
  834.     hr = m_pDMO->QueryInterface(IID_IDMOQualityControl, (void **) &pQC);
  835.     if (SUCCEEDED(hr))
  836.     {
  837.         m_CheckOutQC.SetCheck(TRUE);
  838.         pQC->Release();
  839.     }
  840. }
  841.  
  842.